#include <core/thread/thread_pool.h>
#include <core/time/time.h>

#include "BondContainer.h"
#include "BondLiquidity.h"
#include "CompanyReport.h"
#include "HighYieldBond.h"
#include "IssuerLiquidity.h"
#include "SSVContainer.h"
#include "ThirdPartyGuarantee.h"
#include "qbprotocol/include/SSFilters.h"

typedef qb::base::threadpool threadpool;

namespace {
/*
        两大优化策略
        1.并行过滤
        2.提前测试:动态测试条件
*/
class FilterUtil {
 public:
  // 所有的检测函数,返回true表示检测通过,false将立即中断检查
  // 原先检测条件参见CSSVContainer::IsSSEFIBondPassCondition
  // 有几个条件,名称要取反
#define DEF_FUNC(NAME, BODY)                                                  \
  inline static bool NAME(CBondContainer& gc, int nIndex,                     \
                          const CBondInfo& info, const BLHCONDITION& condStr, \
                          bool bSecondaryMarket, bool bAttention) {           \
    return BODY;                                                              \
  }

  typedef bool (*FilterFunc)(CBondContainer& gc, int nIndex,
                             const CBondInfo& info, const BLHCONDITION& condStr,
                             bool bSecondaryMarket, bool bAttention);

  DEF_FUNC(IsBCQuoteValid, gc.IsBCQuoteValid(condStr, nIndex));  // 有报价
  DEF_FUNC(IsNewBond, info.IsNewBond());                         // 新发债
  DEF_FUNC(IsHasPrice, gc.IsHasPrice(condStr, nIndex,
                                     CBondContainer::SingleValid));  // 有效报价
  DEF_FUNC(IsBothValid, gc.IsHasPrice(condStr, nIndex,
                                      CBondContainer::BothValid));  // 双边报价
  DEF_FUNC(IsBidValid,
           gc.IsHasPrice(condStr, nIndex, CBondContainer::BidValid));  // Bid
  DEF_FUNC(IsOfrValid,
           gc.IsHasPrice(condStr, nIndex, CBondContainer::OfrValid));  // Bid
  DEF_FUNC(CheckBidPrice, gc.CheckBidPrice(condStr, nIndex));          // bid
  DEF_FUNC(CheckOfrPrice, gc.CheckOfrPrice(condStr, nIndex));          // ofr
  DEF_FUNC(GetVolBidCompare, gc.GetVolBidCompare(condStr, nIndex));  // vol.bid
  DEF_FUNC(GetVolOfrCompare, gc.GetVolOfrCompare(condStr, nIndex));  // vol.ofr
  DEF_FUNC(CheckBidOfrPrice, gc.CheckBidOfrPrice(condStr, nIndex));  // bid-ofr
  DEF_FUNC(GetBidCdcCompare, gc.GetBidCdcCompare(condStr, nIndex));  // bid-中债
  DEF_FUNC(GetCdcOfrCompare, gc.GetCdcOfrCompare(condStr, nIndex));  // 中债-ofr

  DEF_FUNC(IsNotExpireBond,
           !info.IsExpireBond());  // 到期债券========================
  DEF_FUNC(IsRebated, info.IsRebated());          // 一级半，新发债
  DEF_FUNC(IsMortgage, info.IsMortgage());        // 可质押
  DEF_FUNC(IsCrossMarket, info.IsCrossMarket());  // 跨市场
  DEF_FUNC(GetSOEenterType, gc.GetSOEenterType(condStr, info));  // 国企
  DEF_FUNC(GetBondOffsetEstPrc,
           gc.GetBondOffsetEstPrc(condStr, nIndex));         // 估值偏差
  DEF_FUNC(GetDiffPrice, gc.GetDiffPrice(condStr, nIndex));  // BP差
  DEF_FUNC(CheckCommonUseType, info.CheckCommonUseType(condStr));  // 常用
  DEF_FUNC(CheckBondTypeNew, info.CheckBondTypeNew(condStr));      // 产品
  DEF_FUNC(GetMultiLevel, gc.GetMultiLevel(condStr, info));  // 主体评级
  DEF_FUNC(GetOutlookRatingLevel, gc.GetOutlookRatingLevel(condStr, info));

  DEF_FUNC(GetCDCRatingLevel, gc.GetCDCRatingLevel(condStr, info));  // 中债隐含
  DEF_FUNC(GetCSIRatingLevel, gc.GetCSIRatingLevel(condStr, info));  // 中证隐含
  DEF_FUNC(GetCBRRatingLevel, gc.GetCBRRatingLevel(condStr, info));  // 中债资信

  DEF_FUNC(GetWarrType, gc.GetWarrType(condStr, info));  // 有担保
  DEF_FUNC(GetMultiCouponType,
           gc.GetMultiCouponType(condStr, info));  // 特殊分类
  DEF_FUNC(HasRight,
           gc.GetRightType(condStr.nRight) == info.IsRight());  // 含权
  DEF_FUNC(CheckRightEx, info.CheckRightEx(condStr));           // 含权类型
  DEF_FUNC(GetMaturityRange,
           gc.GetMaturityRange(condStr, info, bSecondaryMarket));  // 剩余期限
  DEF_FUNC(GetMunicpType, gc.GetMunicpType(condStr, info));        // 城投
  DEF_FUNC(IsInterbank, info.IsInterbank());                       // 银行间
  DEF_FUNC(IsExchange, info.IsExchange());                         // 交易所
  DEF_FUNC(IsSSEBond, info.IsSSEBond());                           // 上交所
  DEF_FUNC(IsSZEBond, info.IsSZEBond());                           // 深交所
  DEF_FUNC(IsBSEBond, info.IsBSEBond());                           // 北交所
  DEF_FUNC(GetMultiInstion, gc.GetMultiInstion(condStr, info));  // 机构类型
  DEF_FUNC(CheckIssuer, info.CheckIssuer(condStr));              // 发行人
  DEF_FUNC(CheckGuarantor, info.CheckGuarantor(condStr));        // 担保人
  DEF_FUNC(CheckSector, info.CheckSector(condStr));              // 行业
  DEF_FUNC(CheckSector2021, info.CheckSector2021(condStr));      // 行业
  DEF_FUNC(CheckHotType, gc.CheckHotType(condStr, info));        // 热门筛选
  DEF_FUNC(CheckArea, info.CheckArea(condStr));                  // 地区
  DEF_FUNC(CheckBontSubType, info.CheckBontSubType(condStr));    // 细分
  DEF_FUNC(CheckDebtRating, info.CheckDebtRating(condStr));      // 债项评级
  DEF_FUNC(CheckFinDebt, info.CheckFinDebt(condStr));            // 金融债
  DEF_FUNC(IsPlatformType, gc.IsPlatformType(condStr, info));    // 平台债
  DEF_FUNC(IsLocalBond, gc.IsLocalBond(condStr, info));          // 地方债
  DEF_FUNC(CheckNCDRating,
           info.CheckNCDRating(condStr));  // NCD      add  by  lbl

  DEF_FUNC(CheckIssueYear, info.CheckIssueYear(condStr));  // 发行年份
  DEF_FUNC(
      GetStateType,
      gc.GetStateType(condStr,
                      info));  // 0=全部，1=今日簿记建档，2=当日发行，3=当日公告
  DEF_FUNC(GetIssueStartDate, gc.GetIssueStartDate(condStr, info));  // 发行日期
  DEF_FUNC(CheckUnderwriter, info.CheckUnderwriter(condStr));        // 在团
  DEF_FUNC(IsCreditBond, info.IsCreditBond(condStr));  // 信用债,利率债
  DEF_FUNC(IsInDays, info.IsInDays(condStr));
  DEF_FUNC(GetDeadLineRange, gc.GetDeadLineRange(condStr, info));  // 期限筛选
  DEF_FUNC(GetExchangeType, gc.GetExchangeType(condStr, info));  // 交易所类型
  DEF_FUNC(IsETSBondType, gc.IsETSBondType(condStr, info));      // 永续债
  DEF_FUNC(IsSubordinatedType, gc.IsSubordinatedType(condStr, info));  // 次级债
  DEF_FUNC(CheckMarketMakeTargetType,
           gc.CheckMarketMakeTargetType(condStr, info));         // 做市标的
  DEF_FUNC(CheckBankBondType, info.CheckBankBondType(condStr));  // 银行业
  DEF_FUNC(IsCorpBondType, gc.IsCorpBondType(condStr, info));    // 公司债
  DEF_FUNC(CheckAssetStatus, info.CheckAssetStatus(condStr));    // 发行
  DEF_FUNC(IsNoExpireInHoliday, !info.IsExpireInHoliday());      // 不含假期
  DEF_FUNC(CheckSettlement, gc.CheckSettlement(condStr, nIndex));  // 清算速度
  DEF_FUNC(CheckCouponRate, info.CheckCouponRate(condStr));  // 票面利率
  DEF_FUNC(CheckMuniArea, info.CheckMuniArea(condStr));      // 城投地区
  DEF_FUNC(CheckLocalBondArea, info.CheckLocalBondArea(condStr));  // 地方债地区
  DEF_FUNC(CheckCategoryFlag, info.CheckCategoryFlag(condStr));  // 专项债

  DEF_FUNC(CheckBondLiquidity,
           CBondLiquidity::instance().CheckLiquidity(nIndex,
                                                     condStr));  // 债券流动性
  DEF_FUNC(CheckIssuerLiquidity,
           CIssuerLiquidity::instance().CheckLiquidity(nIndex,
                                                       condStr));  // 主体流动性
  DEF_FUNC(CheckPrincipalPayType,
           gc.CheckPrincipalPayType(condStr, info));  // 偿还方式
  DEF_FUNC(CheckHighYieldBond,
           CHighYieldBond::instance().CheckHighYieldBond(nIndex,
                                                         condStr));  // 高收益债
  DEF_FUNC(CheckCDCValuationRange,
           gc.CheckCDCValuationRange(condStr, nIndex));  // 中债估值

  DEF_FUNC(CheckThirdPartyGuaranteeBond,
           CThirdPartyGuarantee::instance().CheckBond(nIndex,
                                                      condStr));  // 三方担保人

  inline static bool QuikFilterHasReport(CBondContainer& gc, int nIndex,
                                         const CBondInfo& info,
                                         const BLHCONDITION& condStr,
                                         bool bSecondaryMarket,
                                         bool bAttention) {
    if (condStr.nHasFlg == 1 || condStr.nBothFlg == 1 ||
        condStr.nBidValid == 1 || condStr.nOfrValid == 1 ||
        condStr.nSettlement[0] != CBondContainer::StmAll ||
        condStr.sBPrice[0] != '\0' || condStr.sBPriceEnd[0] != '\0' ||
        condStr.sOPrice[0] != '\0' || condStr.sOPriceEnd[0] != '\0' ||
        condStr.sBidOfr[0] != '\0' || condStr.sBidOfrEnd[0] != '\0' ||
        condStr.sBidCdc[0] != '\0' || condStr.sBidCdcEnd[0] != '\0' ||
        condStr.sCdcOfr[0] != '\0' || condStr.sCdcOfrEnd[0] != '\0' ||
        condStr.sVolBid[0] != '\0' || condStr.sVolOfr[0] != '\0') {
      CBondCompanyRep* ptmp = gc.GetCompanyRep(nIndex);
      if (ptmp && ptmp->GetSize() > 0) return true;
      return false;
    }
    return true;
  }
};

class RuntimeFilter {
 protected:
  typedef std::vector<FilterUtil::FilterFunc> FilterVec;
  const BLHCONDITION* m_cond;
  bool m_bSecondaryMarket;
  bool m_bAttention;
  FilterVec m_funcs;
  CBondContainer* m_container;

 public:
  explicit RuntimeFilter(const RuntimeFilter& filter)
      : m_cond(filter.m_cond),
        m_bSecondaryMarket(filter.m_bSecondaryMarket),
        m_bAttention(filter.m_bAttention),
        m_funcs(filter.m_funcs),
        m_container(filter.m_container) {}
  explicit RuntimeFilter(const BLHCONDITION* condStr, bool bSecondaryMarket,
                         bool bAttention)
      : m_cond(condStr),
        m_bSecondaryMarket(bSecondaryMarket),
        m_bAttention(bAttention),
        m_container(&CBondContainer::instance()) {
    ApplyFuncs();
  }
  RuntimeFilter& operator=(const RuntimeFilter& filter) {
    m_bSecondaryMarket = filter.m_bSecondaryMarket;
    m_bAttention = filter.m_bAttention;
    m_funcs = filter.m_funcs;
    m_cond = filter.m_cond;
    return *this;
  }
  bool CheckValid(int index) const {
    if (!m_container->IsValidIndex(index)) return false;
    const BLHCONDITION& condStr = *m_cond;
    const CBondInfo& info = m_container->ElementAtR(index);
    for (int i = 0; i < (int)m_funcs.size(); i++) {
      if (!m_funcs[i](*m_container, index, info, condStr, m_bSecondaryMarket,
                      m_bAttention))
        return false;
    }
    return true;
  }
  int GetFuncCount() const { return m_funcs.size(); }

 protected:
  void ApplyFuncs() {
    // 等同于CSSVContainer::IsBondPassCondition
    const BLHCONDITION& condStr = *m_cond;
    m_funcs.clear();
    if (condStr.sCompanyid[0] == 'e') {  // 交易所
      if (condStr.nHasFlg != 0) m_funcs.push_back(FilterUtil::IsHasPrice);
      if (condStr.nBothFlg != 0) m_funcs.push_back(FilterUtil::IsBothValid);
      if (condStr.nBidValid != 0) m_funcs.push_back(FilterUtil::IsBidValid);
      if (condStr.nOfrValid != 0) m_funcs.push_back(FilterUtil::IsOfrValid);
      if (condStr.sBPrice[0] != '\0' || condStr.sBPriceEnd[0] != '\0')
        m_funcs.push_back(FilterUtil::CheckBidPrice);
      if (condStr.sOPrice[0] != '\0' || condStr.sOPriceEnd[0] != '\0')
        m_funcs.push_back(FilterUtil::CheckOfrPrice);
      if (condStr.sVolBid[0] != '\0')
        m_funcs.push_back(FilterUtil::GetVolBidCompare);
      if (condStr.sVolOfr[0] != '\0')
        m_funcs.push_back(FilterUtil::GetVolOfrCompare);
      if (condStr.sBidOfr[0] != '\0' || condStr.sBidOfrEnd[0] != '\0')
        m_funcs.push_back(FilterUtil::CheckBidOfrPrice);
      if (condStr.sBidCdc[0] != '\0' || condStr.sBidCdcEnd[0] != '\0')
        m_funcs.push_back(FilterUtil::GetBidCdcCompare);
      if (condStr.sCdcOfr[0] != '\0' || condStr.sCdcOfrEnd[0] != '\0')
        m_funcs.push_back(FilterUtil::GetCdcOfrCompare);
    } else {
      m_funcs.push_back(FilterUtil::QuikFilterHasReport);
    }
    if (condStr.nNewFlg != 0) m_funcs.push_back(FilterUtil::IsNewBond);
    if (condStr.nMatFlg != 0) m_funcs.push_back(FilterUtil::IsNotExpireBond);
    if (condStr.nASemi != 0) m_funcs.push_back(FilterUtil::IsRebated);
    if (condStr.nMortgt != 0) m_funcs.push_back(FilterUtil::IsMortgage);
    if (condStr.nCrosmk != 0) m_funcs.push_back(FilterUtil::IsCrossMarket);
    if (condStr.nEntrTyp != 0) m_funcs.push_back(FilterUtil::GetSOEenterType);
    if (condStr.nCommonUse[0] != CBondContainer::CommAll)
      m_funcs.push_back(FilterUtil::CheckCommonUseType);
    if (condStr.nTypeNew[0] != CBondContainer::newBondAll)
      m_funcs.push_back(FilterUtil::CheckBondTypeNew);
    if (condStr.nIssuerRating[0] != CBondContainer::RatingAll)
      m_funcs.push_back(FilterUtil::GetMultiLevel);
    if (condStr.nOutlookRating[0] != CBondContainer::OutlookRatingAll)
      m_funcs.push_back(FilterUtil::GetOutlookRatingLevel);
    if (condStr.nCDCRating[0] != CBondContainer::CDCRatingAll)
      m_funcs.push_back(FilterUtil::GetCDCRatingLevel);  // 中债隐含
    if (condStr.nCSIRating[0] != CBondContainer::CSIRatingAll)
      m_funcs.push_back(FilterUtil::GetCSIRatingLevel);  // 中证隐含
    if (condStr.nCBRRating[0] != CBondContainer::CBRRatingAll)
      m_funcs.push_back(FilterUtil::GetCBRRatingLevel);  // 中债资信
    if (condStr.nWarrant[0] != CBondContainer::WarrAll)
      m_funcs.push_back(FilterUtil::GetWarrType);  // 有担保
    if (condStr.nCouponType[0] != CBondContainer::CouponAll)
      m_funcs.push_back(FilterUtil::GetMultiCouponType);  // 特殊分类
    // 			if (condStr.nRight !=
    // CBondContainer::RightAll)m_funcs.push_back(FilterUtil::HasRight);
    // //含权
    if (condStr.nRightEx[0] != CBondContainer::RightExAll)
      m_funcs.push_back(FilterUtil::CheckRightEx);  // 含权类型
    if (condStr.nRange[0] != CBondContainer::RangeAll)
      m_funcs.push_back(FilterUtil::GetMaturityRange);  // 剩余期限
    if (condStr.nMunicp[0] != CBondContainer::MunicAll)
      m_funcs.push_back(FilterUtil::GetMunicpType);  // 城投
    if (condStr.szLocalBondArea[0][0] != '\0')
      m_funcs.push_back(FilterUtil::CheckLocalBondArea);  // 地方债地区
    if (condStr.nInterbank != 0)
      m_funcs.push_back(FilterUtil::IsInterbank);  // 银行间
    if (condStr.nExchange != 0)
      m_funcs.push_back(FilterUtil::IsExchange);  // 交易所
    if (condStr.nInstion[0] != CBondContainer::InstAll)
      m_funcs.push_back(FilterUtil::GetMultiInstion);  // 机构类型
    if (condStr.szIssuer[0][0] != '\0')
      m_funcs.push_back(FilterUtil::CheckIssuer);  // 发行人
    if (condStr.szGuarantor[0][0] != '\0')
      m_funcs.push_back(FilterUtil::CheckGuarantor);  // 担保人
    if (condStr.szSector[0][0] != '\0')
      m_funcs.push_back(FilterUtil::CheckSector);  // 行业
    if (condStr.szSector2021[0][0] != '\0')
      m_funcs.push_back(FilterUtil::CheckSector2021);  // 行业
    if (condStr.nPopular[0] != CBondContainer::HotAll)
      m_funcs.push_back(FilterUtil::CheckHotType);  // 热门筛选
    if (condStr.szArea[0][0] != '\0')
      m_funcs.push_back(FilterUtil::CheckArea);  // 地区
    if (condStr.szSubType[0][0] != '\0')
      m_funcs.push_back(FilterUtil::CheckBontSubType);  // 细分
    if (condStr.nDebtRating[0] != CBondContainer::DRatingAll)
      m_funcs.push_back(FilterUtil::CheckDebtRating);  // 债项评级
    if (condStr.nFinDebt[0] != CBondContainer::FinDebtAll)
      m_funcs.push_back(FilterUtil::CheckFinDebt);  // 金融债
    if (condStr.nPlatform[0] != CBondContainer::PlatforamAll)
      m_funcs.push_back(FilterUtil::IsPlatformType);  // 平台债
    if (condStr.nLocalBond[0] != CBondContainer::LocalBondAll)
      m_funcs.push_back(FilterUtil::IsLocalBond);  // 地方债
    if (condStr.nNCDRating[0] != CBondContainer::NCDRatingAll)
      m_funcs.push_back(FilterUtil::CheckNCDRating);  // NCD
    if (condStr.nIssueYear[0] != 0)
      m_funcs.push_back(FilterUtil::CheckIssueYear);  /// 发行年份
    //			if (condStr.nStateType !=
    // 0)m_funcs.push_back(FilterUtil::GetStateType);
    ////0=全部，1=今日簿记建档，2=当日发行，3=当日公告 			if
    //(condStr.szIssueDateB[0] != '\0' && condStr.szIssueDateE[0] !=
    //'\0')m_funcs.push_back(FilterUtil::GetIssueStartDate); //发行日期
    // 			if (condStr.szUnderwriter[0] !=
    // 0)m_funcs.push_back(FilterUtil::CheckUnderwriter);	//在团
    //			if (condStr.nCreditBond !=
    // 0)m_funcs.push_back(FilterUtil::IsCreditBond);
    ////信用债,利率债
    if (condStr.nIssueStartDate[0] > 0 || condStr.nAnnounceDate[0] > 0 ||
        condStr.nPaymentDate[0] > 0 || condStr.nListedDate[0] > 0 ||
        condStr.nInterestStartDate[0] > 0)
      m_funcs.push_back(
          FilterUtil::IsInDays);  // 年份：在发行、公告、缴款或者上市日期间
                                  // 超级新债通过滤时间
    if (condStr.nDeadLineRange[0] != CBondContainer::DL_RangeAll)
      m_funcs.push_back(FilterUtil::GetDeadLineRange);  // 期限筛选
    if (condStr.nListedPlace[0] != CBondContainer::kExchAll)
      m_funcs.push_back(FilterUtil::GetExchangeType);  // 交易所类型
    if (condStr.nETSBond[0] != CBondContainer::ETSBondAll)
      m_funcs.push_back(FilterUtil::IsETSBondType);  // 永续债
    if (condStr.nSubOrdinate[0] != CBondContainer::SubOrdAll)
      m_funcs.push_back(FilterUtil::IsSubordinatedType);  // 次级债
    if (condStr.nMarketMakeTarget[0] != CBondContainer::kMarketMakeAll)
      m_funcs.push_back(FilterUtil::CheckMarketMakeTargetType);  // 做市标的
    if (condStr.nBankBond[0] != CBondContainer::BankAll)
      m_funcs.push_back(FilterUtil::CheckBankBondType);  // 银行业
    if (condStr.nCorpBond[0] != CBondContainer::CorpBondAll)
      m_funcs.push_back(FilterUtil::IsCorpBondType);  // 公司债
    if (condStr.nAssetStatus[0] != CBondContainer::AssetAll)
      m_funcs.push_back(FilterUtil::CheckAssetStatus);  // 发行
    if (condStr.nExpireInHoliday == 1)
      m_funcs.push_back(FilterUtil::IsNoExpireInHoliday);  // 不含假期
    //			if (condStr.nSettlement[0] !=
    // CBondContainer::StmAll)m_funcs.push_back(FilterUtil::CheckSettlement);
    if (condStr.sBondLiquidity[0] != '\0')
      m_funcs.push_back(FilterUtil::CheckBondLiquidity);
    if (condStr.sIssuerLiquidity[0] != '\0')
      m_funcs.push_back(FilterUtil::CheckIssuerLiquidity);
    if (condStr.nPrincipalPayType[0] != '\0' &&
        condStr.nPrincipalPayType[0] != CBondContainer::PPTAll)
      m_funcs.push_back(FilterUtil::CheckPrincipalPayType);  // 偿还方式
    if (condStr.nHighYieldBond[0] != '\0' &&
        condStr.nHighYieldBond[0] != CBondContainer::HYBAll)
      m_funcs.push_back(FilterUtil::CheckHighYieldBond);  // 高收益债
    if (condStr.sCouponRate[0] != '\0' || condStr.sCouponRateEnd[0] != '\0')
      m_funcs.push_back(FilterUtil::CheckCouponRate);  // 票面利率
    if (condStr.sCdcValue[0] != '\0' || condStr.sCdcValueEnd[0] != '\0')
      m_funcs.push_back(FilterUtil::CheckCDCValuationRange);  // 中债估值
    if (condStr.szArea[0][0] != '\0')
      m_funcs.push_back(FilterUtil::CheckArea);  // 地区
    if (condStr.szMuniArea[0][0] != '\0')
      m_funcs.push_back(FilterUtil::CheckMuniArea);  // 城投地区
    if (condStr.szCategoryFlag[0][0] != '\0')
      m_funcs.push_back(FilterUtil::CheckCategoryFlag);  // 专项债
    if (condStr.nThirdPartyGuarantee[0] != CBondContainer::TPGAll)
      m_funcs.push_back(
          FilterUtil::CheckThirdPartyGuaranteeBond);  // 三方担保人
  }
};

using Bonds = std::vector<int>;
Bonds ExtractBonds(const Bonds* source, int start, int end,
                   RuntimeFilter& filter) {
  Bonds bonds;
  qb::base::HighResTime timer;
  for (int i = start; i < end; i++) {
    int index = source->at(i);
    if (filter.CheckValid(index)) bonds.push_back(index);
  }

  return bonds;
}
threadpool& GetFilterThreadPool() {
  static threadpool pool(4);
  return pool;
}
void ParallelExtract(const Bonds& source, BLHCONDITION& condStr, Bonds& result,
                     bool bSecondaryMarket) {
  // 		result.clear();
  // 		if (source.empty())
  // 			return;
  // 		int ncount = source.size();
  // 		int ntest = 100 > ncount ? ncount : 100;
  // 		double time_test, time_total;
  // 		RuntimeFilter filter(&condStr,bSecondaryMarket,true);
  // 		qb::base::HighResTime timer;
  // 		for (int i = 0; i < ntest; i++)
  // 		{
  // 			if (filter.CheckValid(source[i]))
  // 				result.push_back(source[i]);
  // 		}
  // 		time_test = timer.elapsed();
  // 		time_total = time_test*ncount / ntest;
  // 		if (time_total < 1000)
  // 		{
  // 			for (int i = ntest; i < ncount; i++)
  // 			{
  // 				if (filter.CheckValid(source[i]))
  // 					result.push_back(source[i]);
  // 			}
  // 			return;
  // 		}
  // 		int ncpu = 4;
  // 		int nbatch = (ncount - ntest) / ncpu;
  // 		int start = ntest;
  // 		std::vector<std::future<Bonds>> futures; futures.reserve(ncpu);
  // 		threadpool& pool = GetFilterThreadPool();
  // 		for (int i = 0; i < ncpu; i++, start += nbatch){
  // 			int end = start + nbatch;
  // 			if (i + 1 == ncpu)end = ncount;
  // 			futures.push_back(pool.commit(ExtractBonds, &source,
  // start, end, filter));
  // 		}
  //
  // 		for (int i = 0; i < (int)futures.size(); i++)
  // 		{
  // 			double d1, d2;
  // 			qb::base::HighResTime temptimer =
  // qb::base::HighResTime(); 			Bonds&& subbonds =
  // futures[i].get(); 			result.reserve(subbonds.size() + result.size()); 			d1 =
  // temptimer.elapsed(); temptimer = qb::base::HighResTime();
  // for (auto v : subbonds){ 				result.push_back(v);
  // 			}
  // 			d2 = temptimer.elapsed();
  // 		}
}

///////////////////////////////////////////////////////////////
class RuntimeFilterPush : public RuntimeFilter {
 public:
  explicit RuntimeFilterPush(const BLHCONDITION* condStr, bool bSecondaryMarket,
                             bool bAttention)
      : RuntimeFilter(condStr, bSecondaryMarket, bAttention) {
    ApplyFuncs();
  }
};
}  // namespace
void CSSVContainer::Extract(const std::vector<int>& source,
                            std::vector<int>& dest, const BLHCONDITION& condStr,
                            bool bSecondaryMarket) {
  /*
          [性能优化]scofined.qi,2020/08/31
          当前函数的作用,是根据condStr,bSecondaryMarket,将当前m_array_result的数据,抽取放在array_result中
          有三种抽取实现:
          1.原始实现
                  for (int n = 0; n < ncount; n++)
                  {
                          int nIndex = m_array_result[n];
                          if (IsBondPassCondition(nIndex, condStr,
     bSecondaryMarket)) array_result.push_back(nIndex);
                  }
          2.单线程改进实现
                  for (int n = 0; n < ncount; n++)
                  {
                          int nIndex = m_array_result[n];
                          if (filter.CheckValid(nIndex))
                                  array_result.push_back(nIndex);
                  }
          3.多线程实现:
                  ParallelExtract(m_array_result, condStr, array_result,
     bSecondaryMarket);

          经过测试,多线程过滤,性能反而差
          单线程改进,主要是改进IsHasPriceEx中,避免的REPORT的解码
          同时,减少过滤函数,有利于后一步优化
          可供后续改进的措施:根据条件,统一取值,再分段提交给线程池(后续无锁并发处理)
  */
  int ncount = source.size();
  RuntimeFilter filter(&condStr, bSecondaryMarket, true);
  for (int n = 0; n < ncount; n++) {
    int nIndex = source[n];
    if (filter.CheckValid(nIndex)) dest.push_back(nIndex);
  }
  return;
}

void CSSVContainer::UpdateBestPricePush(
    BLHCONDITION& condStr, SSBrokerKeyVector& vct_result,
    SSBrokerKeyVector& vct_resdel, const std::list<xQBBestPriceUnit_c>& qblist,
    bool bSecondaryMarket) {
  RuntimeFilterPush filter(&condStr, bSecondaryMarket, true);
  for (auto& it : qblist) {
    int bondIndex = CBondContainer::instance().GetBondIndex(it.m_bondkey,
                                                            it.m_listedmarket);
    if (!CBondContainer::instance().IsValidIndex(bondIndex)) continue;
    bool bValid = false;
    if (filter.CheckValid(bondIndex))  // 行情无关筛选先做
    {
      REPORT rpt = {0};
      if (CBondContainer::instance().GetCompanyInfoById(it.m_company_id,
                                                        bondIndex, rpt)) {
        if (IsPriceNeedShow(condStr, rpt, bondIndex)) {
          bValid = true;
        }
      }
    }

    BrokerKey bk(it.m_company_id, bondIndex);
    if (bValid)
      vct_result.Insert(bk);
    else
      vct_resdel.Insert(bk);
  }
}

void CSSVContainer::UpdateMixedBestPricePush(
    BLHCONDITION& condStr, SSBrokerKeyVector& vct_result,
    SSBrokerKeyVector& vct_resdel, const QList<xQBMixedBestQuoteUnit_c>& qblist,
    bool bSecondaryMarket) {
  RuntimeFilterPush filter(&condStr, bSecondaryMarket, true);
  std::string contributorId = condStr.GetContributorId();
  for (auto& it : qblist) {
    int bondIndex = CBondContainer::instance().GetBondIndex(it.m_bondkey,
                                                            it.m_listedmarket);
    if (!CBondContainer::instance().IsValidIndex(bondIndex)) continue;
    bool bValid = false;
    if (filter.CheckValid(bondIndex))  // 行情无关筛选先做
    {
      REPORT rpt = {0};
      if (CBondContainer::instance().GetBrokerMixedBPRepById(
              bondIndex, contributorId.c_str(), rpt)) {
        if (IsMixedBestPriceNeedShow(condStr, rpt, bondIndex)) {
          bValid = true;
        }
      }
    }

    BrokerKey bk(condStr.GetContributorId(), bondIndex);
    if (bValid)
      vct_result.Insert(bk);
    else
      vct_resdel.Insert(bk);
  }
}
